package com.yl.zqy.service.impl.sys;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yl.zqy.common.CustomException;
import com.yl.zqy.common.Result;
import com.yl.zqy.dto.SysRoleUserDTO;
import com.yl.zqy.dto.excel.SysUserTemplateExportDTO;
import com.yl.zqy.entity.sys.SysDept;
import com.yl.zqy.entity.sys.SysUser;
import com.yl.zqy.enums.ResultCode;
import com.yl.zqy.mapper.sys.SysUserMapper;
import com.yl.zqy.service.impl.sys.excel.SysUserTemplateExportDTOReadListener;
import com.yl.zqy.service.sys.SysDeptService;
import com.yl.zqy.service.sys.SysUserService;
import com.yl.zqy.utils.CustomRowWriteHandler;
import com.yl.zqy.utils.ExcelUtil;
import com.yl.zqy.utils.QueryUtil;
import com.yl.zqy.vo.common.IPageVo;
import com.yl.zqy.vo.login.LoginVo;
import com.yl.zqy.vo.login.UserPwdVo;
import com.yl.zqy.vo.user.UserInstanceVo;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.yl.zqy.constant.ZQYConstant.USER_UPLOAD_TEMPLATE_FILE_NAME;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author liang.yu
 * @since 2024-03-24
 */
@Service
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private final SysDeptService sysDeptService;

    @Override
    public SysUser getUserByLogin(LoginVo vo) {
        if (StringUtils.isNotEmpty(vo.getUsername()) && StringUtils.isNotEmpty(vo.getPassword())) {
            LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysUser::getUsername, vo.getUsername())
                    .eq(SysUser::getPassword, vo.getPassword());
            return baseMapper.selectOne(queryWrapper);
        }
        return null;
    }

    @Override
    public Result<List<SysUser>> getUserOnline(int current, int size) {
        // 返回数据对象
        List<String> userIds = new ArrayList<>();
        // 获取所有登录的用户ids
        List<String> logIds = StpUtil.searchSessionId("", 0, -1, false);
        // 便利获取登录信息
        SaSession session = null;
        if (current == 1) {
            current = 0;
        }
        for (int i = current * size, len = Math.min(size + i, logIds.size()); i < len; i++) {
            session = StpUtil.getSessionBySessionId(logIds.get(i));
            userIds.add(session.getLoginId().toString());
        }
        List<SysUser> userList = baseMapper.selectBatchIds(userIds);
        return Result.ok(userList);
    }

    @Override
    public Result<Boolean> insertUser(UserInstanceVo vo) {
        SysUser user = new SysUser();
        BeanUtils.copyProperties(vo, user);
        SysDept dept = sysDeptService.getById(vo.getDeptId());
        user.setDeptName(dept.getName());
        int insert = baseMapper.insert(user);
        if (insert > 0) {
            return Result.ok(true);
        }
        return Result.error(false, "新增用户失败！");
    }

    @Override
    public Result<Boolean> updateUser(UserInstanceVo vo) {
        SysUser user = new SysUser();
        BeanUtils.copyProperties(vo, user);
        SysDept dept = sysDeptService.getById(vo.getDeptId());
        user.setDeptName(dept.getName());
        int update = baseMapper.updateById(user);
        if (update > 0) {
            return Result.ok(true);
        }
        return Result.error(false, "修改用户失败！");
    }

    @Override
    public Result<Boolean> deleteById(List<String> ids) {
        int result = baseMapper.deleteBatchIds(ids);
        if (result > 0) {
            return Result.ok(true);
        }
        return Result.error(false, "操作失败！");
    }

    @Override
    public Result<IPageVo<SysUser>> getUserByPage(int current, int size, String deptId, String status, String query) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(StringUtils.isNotBlank(deptId), c -> c.eq(SysUser::getDeptId, deptId))
                .and(StringUtils.isNotBlank(status), c -> c.eq(SysUser::getStatus, status))
                .and(StringUtils.isNotBlank(query), c -> c.like(SysUser::getUsername, query)
                        .or()
                        .like(SysUser::getRealName, query)
                        .or()
                        .like(SysUser::getMobile, query));
        Page<SysUser> sysUserPage = baseMapper.selectPage(Page.of(current, size), queryWrapper);
        return Result.ok(QueryUtil.iPage2IPageVo(sysUserPage));
    }


    @Override
    public int getCountByDeptId(String deptId) {
        return baseMapper.getCountByDeptId(deptId);
    }

    @Override
    public List<SysRoleUserDTO> getUserNotAuthByRoleId(String roleId, String query) {

        return baseMapper.getUserNotAuthByRoleId(roleId, query);
    }

    @Override
    public List<SysRoleUserDTO> getUserAuthByRoleId(String roleId, String query) {
        return baseMapper.getUserAuthByRoleId(roleId, query);
    }

    @Override
    public SysRoleUserDTO getUserInfo(String userId) {

        return baseMapper.getUserInfo(userId);
    }

    @Override
    public Result<Boolean> updatePwd(UserPwdVo vo) {
        String userId = StpUtil.getLoginIdAsString();
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getId, userId).eq(SysUser::getPassword, vo.getOldPwd());
        if (baseMapper.selectCount(queryWrapper) > 0) {
            SysUser user = new SysUser();
            user.setId(userId);
            user.setPassword(vo.getNewPwd());
            return baseMapper.updateById(user) > 0 ? Result.ok() : Result.error("修改密码失败！");

        }
        return Result.error("当前密码不正确，不能就行密码修改！");
    }

    @Override
    public void exportDefaultUsers(HttpServletResponse response) {
        String fileName = USER_UPLOAD_TEMPLATE_FILE_NAME;
        String sheetName = fileName;
        ExcelWriter excelWriter = ExcelUtil.getExcelWriter(fileName, response);
        //创建sheet写入excel
        WriteSheet writeSheet = EasyExcelFactory.writerSheet(0, sheetName)
                .head(SysUserTemplateExportDTO.class)
                .registerWriteHandler(new CustomRowWriteHandler()).build();
        excelWriter.write(new ArrayList<>(), writeSheet);
        excelWriter.finish();
    }

    @Override
    @Transactional
    public Boolean uploadUsersRead(MultipartFile file) {
        List<SysUser> list = new ArrayList<>();
        List<SysDept> deptList = sysDeptService.getBaseMapper().selectList(null);
        Optional.ofNullable(deptList).orElseThrow(() -> new CustomException(ResultCode.SERVER_ERROR, "当前没有部门信息，请先创建部门！"));
        try {
            InputStream fileInputStream = file.getInputStream();
            EasyExcel.read(
                    fileInputStream,
                    SysUserTemplateExportDTO.class,
                    new SysUserTemplateExportDTOReadListener(list, deptList)).sheet().doRead();
        } catch (IOException e) {
            throw new CustomException(ResultCode.FILE_LOAD_ERROR);
        }
        Optional.ofNullable(list).orElseThrow(() -> new CustomException(ResultCode.FILE_LOAD_ERROR, "解析Excel失败！"));
        return saveBatch(list);
    }
}
